﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/*
Code_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 max_stack;
    u2 max_locals;
    u4 code_length;
    u1 code[code_length];
    u2 exception_table_length;
    {   u2 start_pc;
        u2 end_pc;
        u2 handler_pc;
        u2 catch_type;
    } exception_table[exception_table_length];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}
*/
namespace jvm.classfile.attributeinfo
{
    class ExceptionTableEntry : AttributeInfo
    {
        public ushort startPc;
        public ushort endPc;
        public ushort handlerPc;
        public ushort catchType;

        public override void Read(ClassReader reader)
        {
            startPc = reader.ReadUshort();
            endPc = reader.ReadUshort();
            handlerPc = reader.ReadUshort();
            catchType = reader.ReadUshort();
        }
    }

    class CodeAttribute : AttributeInfo
    {
        public ushort maxStack;
        public ushort maxLocals;
        public byte[] code;
        public ExceptionTableEntry[] exceptionTable;
        public AttributeInfo[] attributes;

        public override void Read(ClassReader reader)
        {
            maxStack = reader.ReadUshort();
            maxLocals = reader.ReadUshort();
            uint code_length = reader.ReadUint();
            code = reader.ReadBytes(code_length);
            ushort exception_table_length = reader.ReadUshort();
            exceptionTable = new ExceptionTableEntry[exception_table_length];
            for (int i = 0; i < exception_table_length; i++)
            {
                exceptionTable[i] = new ExceptionTableEntry();
                exceptionTable[i].Read(reader);
            }
            ushort attributes_count = reader.ReadUshort();
            attributes = new AttributeInfo[attributes_count];
            for (int i = 0; i < attributes_count; i++)
            {
                attributes[i] = AttrFactory.Create(reader, constantPool);
                attributes[i].Read(reader);
            }
        }

        public LineNumberTableAttribute LineNumberTableAttribute
        {
            get
            {
                foreach (AttributeInfo attributeInfo in attributes)
                {
                    if (attributeInfo.GetType() == typeof(LineNumberTableAttribute))
                    {
                        return (LineNumberTableAttribute)attributeInfo;
                    }
                }
                return null;
            }
        }
    }
}
